Daily trade alerts for XHV

Mark Ziemann https://mdz-analytics.com

2022-09-26

Source code

Intro

In the backtesting analysis, I have established several different profitable strategies for timing entry/exits. Visit the XHV page to see how these signals were identified.

  1. Simple moving average (SMA)

  2. Exponential moving average (EMA)

  3. SMA crosses

  4. EMA crosses

  5. Directional movement index (DMI)

  6. True strength index (TSI) BEST

  7. Stochastic oscillator (stoch)

  8. Double RSI

  9. Donchian channel

  10. Ensembl indicator

This script will examine the price action and these trade signals just before the daily close. If the signal is TRUE, it is bullish and if FALSE it is bearish. When there is a switch from bearish to bullish it is a buy signal and when it switches from bullish to bearish it is a sell signal. This HTML is updated just before the daily close each day, but push notifications for any trade signals are also sent by push bullet.

To receive these signals in real-time, subscribe to the following channels - it’s free for a limited time!

https://www.pushbullet.com/channel?tag=xhv_signal

If you need some help to design your own trading signals/strategies, I am happy to help for a fee. email me at mark.ziemann{αt}gmail.com for any enquiries/suggestions/feedback.

This report is distributed for FREE under the MIT licence, but if you find it useful, consider a small tip.

Monero Address

Reminder: this analysis is not financial advice.

suppressPackageStartupMessages({
  library("jsonlite")
  library("tidyverse")
  library("runner")
  library("quantmod")
  library("TTR")
  library("RPushbullet")
  library("kableExtra")
})

TESTING = FALSE

MYNOTE = NULL
mydate <- Sys.time()
attr(mydate, "tzone") <- "UTC"
mydate <- as.Date(mydate)

Get XHV parameters

params <- read.table("https://mdz-analytics.com/coins/XHV/XHV_dat.txt", header=TRUE)
params %>% kbl(caption="optimised backtested parameters") %>%  kable_styling("hover", full_width = F)
optimised backtested parameters
indicator parameter meanROI totalROI ntrades ndays xhodl
SMA 50 1.369064 107.60904 35 1599 -123.26644
EMA 63 1.340786 53.08207 32 1599 -60.80566
SMAcross 42,5 1.654473 153.39934 20 1599 -175.71935
EMAcross 27,7 1.680600 210.80443 18 1599 -241.47704
DMI 24 1.223288 25.50767 38 1599 -29.21910
DC 20 1.548742 90.20343 19 1599 -103.32827
TSI 56,39,9 1.640064 1117.79097 20 1599 -1280.43255
stoch 34,76,6 1.502464 1479.62193 25 1599 -1694.91087
RSI2 61,107 1.198093 99.80300 53 1599 -114.32460
Ensemble DMI,stoch,1 1.216304 13.82820 37 1599 -15.72256

Get XHV price data

Obtaining XHV price data (daily) for the last 300 days and today’s price.

URL="https://web-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical?symbol=XHV&convert=USD&interval=daily&count=300"
download.file(URL,destfile="xhvdat.txt")
xhvdat <- fromJSON("xhvdat.txt")
price <- xhvdat$data$quotes
price <- data.frame(  as.Date(price$time_close) , price$quote$USD$high, price$quote$USD$low, price$quote$USD$close)
colnames(price) <- c("date","high","low","close")

URL="https://web-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical?symbol=XHV&convert=USD&interval=hourly&time_period=hourly&count=11"
download.file(URL,destfile="xhvdat.txt")
xhvdat <- fromJSON("xhvdat.txt")
price2 <- xhvdat$data$quotes
price2 <- data.frame( as.Date(price2$time_close) , price2$quote$USD$high, price2$quote$USD$low, price2$quote$USD$close,stringsAsFactors=FALSE)
colnames(price2) <- c("date","high","low","close")

high <- max(price2[,2])
low <-  min(price2[,3])
close <- price2[nrow(price2),4]

df <- data.frame(date=mydate,high=high,low=low,close=close,stringsAsFactors=FALSE)
price <- rbind(price,df)
tail(price) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close
2022-09-21 0.4458335 0.4111750 0.4157633
2022-09-22 0.4429768 0.4111331 0.4340045
2022-09-23 0.4702876 0.4290004 0.4393697
2022-09-24 0.4454243 0.4313196 0.4388200
2022-09-25 0.4418418 0.4220523 0.4267899
2022-09-26 0.4309843 0.4225514 0.4303485
if ( TESTING == TRUE) {
  price[nrow(price),"Close"] <- price[nrow(price),"Close"] * 2
}

XHV SMA indicator

Now to determine whether XHV has crossed the SMA line.

price2 <- price

n <- as.numeric(params[params$indicator == "SMA",2])

price2$ma <- SMA(Cl(price2),n=n)
price2$signal <- price2$close > price2$ma
tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close ma signal
2022-09-21 0.4458335 0.4111750 0.4157633 0.5440337 FALSE
2022-09-22 0.4429768 0.4111331 0.4340045 0.5420838 FALSE
2022-09-23 0.4702876 0.4290004 0.4393697 0.5392298 FALSE
2022-09-24 0.4454243 0.4313196 0.4388200 0.5362468 FALSE
2022-09-25 0.4418418 0.4220523 0.4267899 0.5327173 FALSE
2022-09-26 0.4309843 0.4225514 0.4303485 0.5280983 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xhv_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xhv_signal="SELL"
  }
} else {
xhv_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_SMA=TRUE
} else {
  ens_SMA=FALSE
}

message(paste("XHV SMA signal:",xhv_signal))
## XHV SMA signal: NONE
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="XHV w SMA")
grid()
lines(price2$ma~ as.Date(price2$date) ,col="red")

if ( xhv_signal != "NONE") {
  MYNOTE <- paste("The XHV SMA signal is", xhv_signal,".")
}

XHV EMA indicator

Now to determine whether XHV has crossed the EMA line.

price2 <- price

n <- as.numeric(params[params$indicator == "EMA",2])

price2$ma <- EMA(Cl(price2),n=n)
price2$signal <- price2$close > price2$ma
tail(price2) %>% kbl(row.names = FALSE) %>%  kable_styling("hover", full_width = F)
date high low close ma signal
2022-09-21 0.4458335 0.4111750 0.4157633 0.5779222 FALSE
2022-09-22 0.4429768 0.4111331 0.4340045 0.5734248 FALSE
2022-09-23 0.4702876 0.4290004 0.4393697 0.5692355 FALSE
2022-09-24 0.4454243 0.4313196 0.4388200 0.5651600 FALSE
2022-09-25 0.4418418 0.4220523 0.4267899 0.5608360 FALSE
2022-09-26 0.4309843 0.4225514 0.4303485 0.5567582 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xhv_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xhv_signal="SELL"
  }
} else {
  xhv_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_EMA=TRUE
} else {
  ens_EMA=FALSE
}

message(paste("XHV EMA signal:",xhv_signal))
## XHV EMA signal: NONE
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="XHV EMA")
grid()
lines(price2$ma~ as.Date(price2$date) ,col="red")

if ( xhv_signal != "NONE") {
  MYNOTE <- paste("The XHV EMA signal is", xhv_signal,".")
}

XHV SMA cross indicator

The SMA cross is a reasonably good strategy.

price2 <- price

n <- as.numeric(unlist(strsplit(params[params$indicator == "SMAcross",2],",")))
n1 <- n[1]
n2 <- n[2]

price2$ma1 <- SMA(Cl(price2),n=n1)
price2$ma2 <- SMA(Cl(price2),n=n2)

price2$signal <- price2$ma2 > price2$ma1
tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close ma1 ma2 signal
2022-09-21 0.4458335 0.4111750 0.4157633 0.5300507 0.4577330 FALSE
2022-09-22 0.4429768 0.4111331 0.4340045 0.5255662 0.4441779 FALSE
2022-09-23 0.4702876 0.4290004 0.4393697 0.5213931 0.4370671 FALSE
2022-09-24 0.4454243 0.4313196 0.4388200 0.5165255 0.4311250 FALSE
2022-09-25 0.4418418 0.4220523 0.4267899 0.5120386 0.4309495 FALSE
2022-09-26 0.4309843 0.4225514 0.4303485 0.5090288 0.4338665 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xhv_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xhv_signal="SELL"
  }
} else {
xhv_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_SMAcross=TRUE
} else {
  ens_SMAcross=FALSE
}

message(paste("XHV SMA cross signal:",xhv_signal))
## XHV SMA cross signal: NONE
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="XHV w SMA cross")
grid()
lines(price2$ma1~ as.Date(price2$date) ,col="red")
lines(price2$ma2~ as.Date(price2$date) ,col="blue")

if ( xhv_signal != "NONE") {
  MYNOTE <- paste(MYNOTE, "The XHV SMA cross signal is", xhv_signal,".")
}

XHV EMA cross indicator

The EMA cross is a moderately profitable strategy.

price2 <- price

n <- as.numeric(unlist(strsplit(params[params$indicator == "EMAcross",2],",")))
n1 <- n[1]
n2 <- n[2]

price2$ma1 <- EMA(Cl(price2),n=n1)
price2$ma2 <- EMA(Cl(price2),n=n2)

price2$signal <- price2$ma2 > price2$ma1
tail(price2) %>% kbl(row.names = FALSE) %>%  kable_styling("hover", full_width = F)
date high low close ma1 ma2 signal
2022-09-21 0.4458335 0.4111750 0.4157633 0.5066037 0.4618079 FALSE
2022-09-22 0.4429768 0.4111331 0.4340045 0.5014181 0.4548570 FALSE
2022-09-23 0.4702876 0.4290004 0.4393697 0.4969860 0.4509852 FALSE
2022-09-24 0.4454243 0.4313196 0.4388200 0.4928313 0.4479439 FALSE
2022-09-25 0.4418418 0.4220523 0.4267899 0.4881141 0.4426554 FALSE
2022-09-26 0.4309843 0.4225514 0.4303485 0.4839880 0.4395787 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xhv_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xhv_signal="SELL"
  }
} else {
  xhv_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_EMAcross=TRUE
} else {
  ens_EMAcross=FALSE
}

message(paste("XHV EMA cross signal is",xhv_signal))
## XHV EMA cross signal is NONE
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="XHV EMA cross")
grid()
lines(price2$ma1~ as.Date(price2$date) ,col="red")
lines(price2$ma2~ as.Date(price2$date) ,col="blue")

if ( xhv_signal != "NONE") {
  MYNOTE <- paste(MYNOTE, "The XHV EMA cross signal is", xhv_signal,".")
}

XHV DMI indicator

Directional movement indicator is a good approach to identify trend changes.

n <- as.numeric(params[params$indicator == "DMI",2])

dmi.adx <- ADX(price[,c("high","low","close")],n=n)
price2 <- cbind(price,dmi.adx)
price2$signal <- dmi.adx[,1] > dmi.adx[,2]
tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close DIp DIn DX ADX signal
2022-09-21 0.4458335 0.4111750 0.4157633 16.43160 21.49912 13.359940 7.892779 FALSE
2022-09-22 0.4429768 0.4111331 0.4340045 16.00269 20.94137 13.367985 8.120912 FALSE
2022-09-23 0.4702876 0.4290004 0.4393697 17.71319 20.22704 6.625827 8.058617 FALSE
2022-09-24 0.4454243 0.4313196 0.4388200 17.50039 19.98405 6.625827 7.998918 FALSE
2022-09-25 0.4418418 0.4220523 0.4267899 17.19791 20.44805 8.633436 8.025356 FALSE
2022-09-26 0.4309843 0.4225514 0.4303485 17.06674 20.29209 8.633436 8.050693 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xhv_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xhv_signal="SELL"
  }
} else {
  xhv_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_DMI=TRUE
} else {
  ens_DMI=FALSE
}

message(paste("XHV DMI signal:",xhv_signal))
## XHV DMI signal: NONE
price2 <- as.data.frame(price2)
par(mfrow=c(2,1))
plot(price2$close~as.Date(price2$date),type="l",
  xlab="Date",ylab="price (USD)",main="XHV USD price")
grid()
plot(price2$DIp~as.Date(price2$date),type="l", col="blue",
  xlab="Date",ylab="price (USD)",main="XHV DMI")
grid()
lines(price2$DIn ~ as.Date(price2$date) ,col="red")

if ( xhv_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"XHV DMI signal is", xhv_signal,".")
}

XHV TSI indicator

True Strength Indicator is one of the more profitable approaches. Its success lies in how it changes rapidly when momentum shifts. For most coins, this indicator performs “best” in backtesting analysis, which means it should carry relatively more weight than other indicators.

n <- as.numeric(unlist(strsplit(params[params$indicator == "TSI",2],",")))
n1 <- n[1]
n2 <- n[2]
ns <- n[3]

TSI <- function(x, n.first = 25, n.second = 13, n.signal = 7) {
  #True Strength Indicator
  #https://school.stockcharts.com/doku.php?id=technical_indicators:true_strength_index
  x <- try.xts(x, error = as.matrix)
  pc <- x - lag.xts(x, na.pad = T) #force lag.xts to get na padding
  dspc <- EMA(EMA(pc, n = n.first), n = n.second)
  dsapc <- EMA(EMA(abs(pc), n = n.first), n = n.second)

  tsi <- 100 * (dspc/dsapc)
  signal <- EMA(tsi, n = n.signal)
  r <- cbind(tsi, signal)
  r <- reclass(r, x)
  if (!is.null(dim(r))) colnames(r) <- c("tsi", "signal")
  return(r)
}

tsi <- TSI(price$close , n.first = n1, n.second = n2, n.signal = ns )
colnames(tsi) <- c("tsi","sig")

price2 <- cbind(price,tsi)
price2$signal <- tsi[,1] > tsi[,2]
tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close tsi sig signal
2022-09-21 0.4458335 0.4111750 0.4157633 -11.24073 -10.80968 FALSE
2022-09-22 0.4429768 0.4111331 0.4340045 -11.44477 -10.93670 FALSE
2022-09-23 0.4702876 0.4290004 0.4393697 -11.60816 -11.07099 FALSE
2022-09-24 0.4454243 0.4313196 0.4388200 -11.76548 -11.20989 FALSE
2022-09-25 0.4418418 0.4220523 0.4267899 -11.96938 -11.36179 FALSE
2022-09-26 0.4309843 0.4225514 0.4303485 -12.14194 -11.51782 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xhv_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xhv_signal="SELL"
  }
} else {
  xhv_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_TSI=TRUE
} else {
  ens_TSI=FALSE
}

message(paste("XHV TSI signal:",xhv_signal))
## XHV TSI signal: NONE
par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(tsi[,1] ~ as.Date(price2$date),type="l",col="blue",
  xlab="Date",ylab="TSI",main="TSI")
lines(as.Date(price2$date), tsi[,2]  , col="red"  )
grid()

par(mfrow=c(1,1))
if ( xhv_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"XHV TSI signal is", xhv_signal,".")
}

XHV stochastic oscillator indicator

Similar to the TSI, the stoch can pinpoint early changes in momentum, however it may give many false positives.

n <- as.numeric(unlist(strsplit(params[params$indicator == "stoch",2],",")))
n1 <- n[1]
n2 <- n[2]
n3 <- n[3]

sto <- stoch(HLC(price), nFastK=n1 , nFastD=n2 , nSlowD=n2 , bounded = TRUE, smooth=n3)

price2 <- cbind(price,sto)
price2$signal <- price2$fastK > price2$fastD

tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close fastK fastD slowD signal
2022-09-21 0.4458335 0.4111750 0.4157633 0.1601180 0.3624296 0.2477146 FALSE
2022-09-22 0.4429768 0.4111331 0.4340045 0.1254689 0.3616850 0.2511687 FALSE
2022-09-23 0.4702876 0.4290004 0.4393697 0.0958554 0.3600745 0.2545829 FALSE
2022-09-24 0.4454243 0.4313196 0.4388200 0.0885286 0.3581839 0.2579493 FALSE
2022-09-25 0.4418418 0.4220523 0.4267899 0.0771508 0.3560568 0.2612578 FALSE
2022-09-26 0.4309843 0.4225514 0.4303485 0.0909479 0.3540836 0.2645064 FALSE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xhv_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xhv_signal="SELL"
  }
} else {
  xhv_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_stoch=TRUE
} else {
  ens_stoch=FALSE
}

message(paste("XHV stoch signal:",xhv_signal))
## XHV stoch signal: NONE
par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(price2$fastK ~ as.Date(price2$date),type="l",col="blue",
  xlab="Date",ylab="index",main="stochastic oscillator")
lines(as.Date(price2$date), price2$fastD  , col="red"  )
grid()

par(mfrow=c(1,1))
if ( xhv_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"XHV Stoch signal is", xhv_signal,".")
}

XHV double RSI indicator

Double RSI is simply two RSI lines.

n <- as.numeric(unlist(strsplit(params[params$indicator == "RSI2",2],",")))
n1 <- n[1]
n2 <- n[2]

rsi1 <- RSI(price$close,n=n1,maType=EMA)
rsi2 <- RSI(price$close,n=n2,maType=EMA)

price2 <- cbind(price,rsi1,rsi2)
price2$signal <- price2$rsi1 > price2$rsi2

tail(price2) %>% kbl(row.names = FALSE) %>% kable_styling("hover", full_width = F)
date high low close rsi1 rsi2 signal
2022-09-21 0.4458335 0.4111750 0.4157633 40.43433 40.91965 FALSE
2022-09-22 0.4429768 0.4111331 0.4340045 41.74046 41.30299 TRUE
2022-09-23 0.4702876 0.4290004 0.4393697 42.12616 41.41691 TRUE
2022-09-24 0.4454243 0.4313196 0.4388200 42.09665 41.40852 TRUE
2022-09-25 0.4418418 0.4220523 0.4267899 41.44026 41.22234 TRUE
2022-09-26 0.4309843 0.4225514 0.4303485 41.71804 41.30188 TRUE
today_signal <- price2[nrow(price2),"signal"]
previous_signal <- price2[(nrow(price2)-1),"signal"]
if (today_signal != previous_signal ) {
  if ( (today_signal == TRUE ) & (previous_signal == FALSE ) ) {
    xhv_signal="BUY"
  }
  if ( (today_signal == FALSE ) & (previous_signal == TRUE ) ) {
    xhv_signal="SELL"
  }
} else {
  xhv_signal <- "NONE"
}

if (today_signal==TRUE) {
  ens_RSI2=TRUE
} else {
  ens_RSI2=FALSE
}

message(paste("XHV RSI signal:",xhv_signal))
## XHV RSI signal: NONE
par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(price2$rsi1 ~ as.Date(price2$date),type="l",col="blue",
  xlab="Date",ylab="index",main="double RSI")
lines(as.Date(price2$date), price2$rsi2  , col="red"  )
grid()

par(mfrow=c(2,1))
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price")
grid()

plot(price2$rsi1/price2$rsi2 ~ as.Date(price2$date),type="l",
  xlab="Date",ylab="RSI ratio",main="double RSI")
grid()
abline(h=1,lty=2,lwd=2)

par(mfrow=c(1,1))
if ( xhv_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"XHV RSI2 signal is", xhv_signal,".")
}

XHV Donchian channel indicator

n <- as.numeric(params[params$indicator == "DC",2])

price2 <- price[1:nrow(price)-1,]
dc <- DonchianChannel(price2$close,n=n)

price2$higher <- c(NA,sapply(2:nrow(dc),function(i) {
  dc[i,"high"] > dc[(i-1),"high"]
} ))
price2$lower <- c(NA,sapply(2:nrow(dc),function(i) {
  dc[i,"low"] < dc[(i-1),"low"]
} ))
price2 <- price2[price2$higher != price2$lower,]
# show changing rows only
price2 <- price2[c(NA,unlist(lapply(2:nrow(price2) , function(i) {
  price2$higher[i] != price2$higher[i-1]
}))),]
price2 <- price2[!is.na(price2$higher),]

previous_signal <- price2[nrow(price2),"higher"]

price2 <- price
dc <- DonchianChannel(price2$close,n=n)
colnames(dc) <- c("dchigh","dcmid","dclow")
price2 <- cbind(price2,dc)

tail(price2) %>% kbl(row.names = FALSE) %>%  kable_styling("hover", full_width = F)
date high low close dchigh dcmid dclow
2022-09-21 0.4458335 0.4111750 0.4157633 0.5449829 0.4803731 0.4157633
2022-09-22 0.4429768 0.4111331 0.4340045 0.5392360 0.4774997 0.4157633
2022-09-23 0.4702876 0.4290004 0.4393697 0.5392360 0.4774997 0.4157633
2022-09-24 0.4454243 0.4313196 0.4388200 0.5392360 0.4774997 0.4157633
2022-09-25 0.4418418 0.4220523 0.4267899 0.5392360 0.4774997 0.4157633
2022-09-26 0.4309843 0.4225514 0.4303485 0.5392360 0.4774997 0.4157633
xhv_signal="NONE"

# if we in negative territory, check whether time to buy
if ( previous_signal == FALSE ) {
  if ( price2[nrow(price2),"dchigh"] > price2[nrow(price2)-1,"dchigh"] ) {
    xhv_signal="BUY"
  }
}

# if we in positive territory, check whether time to sell
if ( previous_signal == TRUE ) {
  if ( price2[nrow(price2),"dclow"] < price2[nrow(price2)-1,"dclow"] ) {
    xhv_signal="SELL"
  }
}

if ( xhv_signal=="NONE" ) {
  today_signal=previous_signal
} else {
  if (xhv_signal=="BUY") { today_signal = TRUE }
  if (xhv_signal=="SELL") { today_signal = FALSE }
}

if (today_signal==TRUE) {
  ens_DC=TRUE
} else {
  ens_DC=FALSE
}

message(paste("XHV DC signal:",xhv_signal))
## XHV DC signal: NONE
plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price",lwd=2)
grid()

lines(price2$dclow~ as.Date(price2$date),lwd=1.5,col="red")
lines(price2$dchigh~ as.Date(price2$date),lwd=1.5,col="limegreen")

price2 <- tail(price2,100)

plot(price2$close ~ as.Date(price2$date),type="l",log="y",
  xlab="Date",ylab="price (USD)",main="USD price",lwd=2)
grid()

lines(price2$dclow~ as.Date(price2$date),lwd=1.5,col="red")
lines(price2$dcmid~ as.Date(price2$date),lwd=1.5,col="gray")
lines(price2$dchigh~ as.Date(price2$date),lwd=1.5,col="limegreen")

if ( xhv_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"XHV Donchian channel signal is", xhv_signal,".")
}

XHV Ensemble indicator

This is a combination of a number of indicators.

ens <- params[params$indicator=="Ensemble","parameter"]
myrev <- intToUtf8(rev(utf8ToInt(ens)))
myrev <- unlist(strsplit(myrev,","))
# get thresh
n <- as.numeric(myrev[1])
myrev <- myrev[2:length(myrev)]
# get combination
combo <- sapply(myrev,function(s) { intToUtf8(rev(utf8ToInt(s))) })

message(paste("The combination is",paste(combo,collapse=" ")))
## The combination is stoch DMI
message(paste("The buy threshold is",n))
## The buy threshold is 1
indicators <- c("SMA"=ens_SMA,
  "EMA"=ens_EMA,
  "SMAcross"=ens_SMAcross,
  "EMAcross"=ens_EMAcross,
  "DMI"=ens_DMI,
  "TSI"=ens_TSI,
  "stoch"=ens_stoch,
  "RSI2"=ens_RSI2,
  "DC"=ens_DC)

indicators <- indicators[names(indicators) %in% combo]
message("State of the indicators:")
## State of the indicators:
indicators
##   DMI stoch 
## FALSE FALSE
today_count <- sum(indicators)
message(paste("today_count_XHV",today_count,sep="="))
## today_count_XHV=0
today_signal <- today_count>=n

prev_html <- readLines("https://mdz-analytics.com/coins/XHV/alerts_XHV.html")
prev_signal <- length(grep("XHV ensemble indicator is BULLISH",prev_html))>2

xhv_signal <- "NONE"

if ( today_signal != prev_signal ) {
  if ( today_signal == TRUE ) {
    xhv_signal="BUY"
  } else {
    xhv_signal="SELL"
  }
}

if (today_signal==TRUE) {
  message("XHV ensemble indicator is BULLISH")
} else {
  message("XHV ensemble indicator is BEARISH")
}
## XHV ensemble indicator is BEARISH
message(paste("XHV ENS signal:",xhv_signal))
## XHV ENS signal: NONE
if ( xhv_signal != "NONE") {
  MYNOTE <- paste(MYNOTE,"XHV Ensemble indicator is", xhv_signal,".")
}

Send a push notification.

MYNOTE
## NULL
if ( !is.null(MYNOTE) ) {
  MYNOTE <- paste(MYNOTE, ". Visit https://mdz-analytics.com/coins/XHV/alerts_XHV.html for the details")
  MYNOTE
  pbPost("note", "Crypto Alert", MYNOTE ,channel="xhv_signal")
}

Session information

For reproducibility


Click HERE to show session info

sessionInfo()
## R version 4.1.2 (2021-11-01)
## Platform: aarch64-unknown-linux-gnu (64-bit)
## Running under: Ubuntu 22.04.1 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/aarch64-linux-gnu/blas/libblas.so.3.10.0
## LAPACK: /usr/lib/aarch64-linux-gnu/lapack/liblapack.so.3.10.0
## 
## locale:
##  [1] LC_CTYPE=en_AU.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_AU.UTF-8        LC_COLLATE=en_AU.UTF-8    
##  [5] LC_MONETARY=en_AU.UTF-8    LC_MESSAGES=en_AU.UTF-8   
##  [7] LC_PAPER=en_AU.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_AU.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] kableExtra_1.3.4  RPushbullet_0.3.4 quantmod_0.4.20   TTR_0.24.3       
##  [5] xts_0.12.1        zoo_1.8-10        runner_0.4.1      forcats_0.5.1    
##  [9] stringr_1.4.0     dplyr_1.0.9       purrr_0.3.4       readr_2.1.2      
## [13] tidyr_1.2.0       tibble_3.1.8      ggplot2_3.3.6     tidyverse_1.3.2  
## [17] jsonlite_1.8.0   
## 
## loaded via a namespace (and not attached):
##  [1] httr_1.4.4          sass_0.4.2          viridisLite_0.4.0  
##  [4] modelr_0.1.8        bslib_0.4.0         assertthat_0.2.1   
##  [7] highr_0.9           googlesheets4_1.0.1 cellranger_1.1.0   
## [10] yaml_2.3.5          pillar_1.8.0        backports_1.4.1    
## [13] lattice_0.20-45     glue_1.6.2          digest_0.6.29      
## [16] rvest_1.0.2         colorspace_2.0-3    htmltools_0.5.3    
## [19] pkgconfig_2.0.3     broom_1.0.0         haven_2.5.0        
## [22] bookdown_0.28       scales_1.2.0        webshot_0.5.3      
## [25] svglite_2.1.0       tzdb_0.3.0          googledrive_2.0.0  
## [28] generics_0.1.3      ellipsis_0.3.2      cachem_1.0.6       
## [31] withr_2.5.0         cli_3.3.0           magrittr_2.0.3     
## [34] crayon_1.5.1        readxl_1.4.1        evaluate_0.16      
## [37] fs_1.5.2            fansi_1.0.3         xml2_1.3.3         
## [40] tools_4.1.2         hms_1.1.1           gargle_1.2.0       
## [43] lifecycle_1.0.1     munsell_0.5.0       reprex_2.0.2       
## [46] compiler_4.1.2      jquerylib_0.1.4     systemfonts_1.0.4  
## [49] rlang_1.0.4         grid_4.1.2          rstudioapi_0.13    
## [52] rmarkdown_2.15      gtable_0.3.0        DBI_1.1.3          
## [55] curl_4.3.2          R6_2.5.1            lubridate_1.8.0    
## [58] knitr_1.39          fastmap_1.1.0       utf8_1.2.2         
## [61] stringi_1.7.8       parallel_4.1.2      rmdformats_1.0.4   
## [64] Rcpp_1.0.9          vctrs_0.4.1         dbplyr_2.2.1       
## [67] tidyselect_1.1.2    xfun_0.32